import functools

def add_func(a,b):
    return a+b

def mul_func(a,b):
    return a*b

n = 5
a_list = list(range(1,n+1))
print(a_list)

triangle_num = functools.reduce(add_func,a_list)
print(triangle_num)
fact_num = functools.reduce(mul_func,a_list)
print(fact_num)

# lambda表达式 匿名函数 动态创建的函数 通常只使用一次 结果可调用 但不会被保存

# 下面两个函数和上面等同效果
triangle_num_alike = functools.reduce(lambda x,y:x+y,[1,2,3,4,5])

fact_num_alike = functools.reduce(lambda x,y:x*y,[1,2,3,4,5])

# 列表推导式
b_list = [i * i for i in a_list]

mult_list = [i * j for i in range(3) for j in range(3)]

my_list = [10, -10, -1, 12, -500, 13, 15, -3]
new_list = [i for i in my_list if i >0]  # 列表推导式最后可加一个可选参数 一般是判断条件

# 集合推导式
my_set = {i for i in my_list if i >0}  # set里不会有重复的值

# 字典推导式
vals_list = [('pi',3.14),('phi',1.168)]
my_dict = {i[0]:i[1] for i in vals_list}

'''将两个列表组成一个字典'''
keys = ['Jan','Carol']
vals = [4.0,3.9]
grade_dict = {keys[i]:vals[i] for i in range(len(keys))}

# 等同于上方的代码 但性能高于之前
# zip() 函数可合并列表 把下标相同的元素放在一起 ('Jan', 4.0) ('Carol', 3.9)
grade_dict_s = {key:val for key,val in zip(keys,vals)}

# 字典推导式可以反转字典
phone_dict = {'Jan':187,'Ted':189}

# 字典items() 之后可以循环再下标的方式取到你想要的值
a = phone_dict.items()  # 以列表的形式返回可遍历的元组数组 dict_items([('Jan', 187), ('Ted', 189)])
print(a)
for i in a:
    print(i)

print('-------------------------')
# 反转字典之后 比如之前能通过 姓名查询电话号码 现在就可以用电话号码查询姓名
idict = {v:k for k,v in phone_dict.items()}

# 将列表传递给函数 可改变原列表的值
def set_list_vals(list_arg):
    list_arg[0] = 100
    list_arg[1] = 200
    list_arg[2] = 150

c_list = [0, 0, 0]
set_list_vals(c_list)
print(c_list)


# 但是下面的操作无法改变原列表的值
def set_list_vals(list_arg_s):
    list_arg_s = [100,200,150]

d_list = [0, 0, 0]
set_list_vals(d_list)
print(d_list)



